/*
 * Copyright Hundsun Technologies Inc. All Rights Reserved.
 */

package account

import (
	"github.com/golang/protobuf/proto"
	"hundsun.com/hsl/hschain/common/types"
	pbcom "hundsun.com/hsl/hschain/protos/common"
	"hundsun.com/hsl/hschain/store/db"
)

// DB 账户存储对象
type DB struct {
	get db.DatabaseGet
}

// NewAccountDB new *DB
func NewAccountDB(get db.DatabaseGet) *DB {
	return &DB{get: get}
}

// GetAccount get account
func (ac *DB) GetAccount(address string) (*pbcom.Account, error) {
	if ac.get == nil {
		return nil, types.ErrNotFound
	}
	v, err := ac.get.Get(GenAccountKey(address))
	if err != nil {
		return nil, err
	}
	acc := &pbcom.Account{}
	err = proto.Unmarshal(v, acc)
	if err != nil {
		return nil, err
	}
	return acc, nil
}

// GetAccounts get accounts
func (ac *DB) GetAccounts(address []string) ([]*pbcom.Account, error) {
	if ac.get == nil {
		return nil, types.ErrNotFound
	}
	keys := make([][]byte, len(address))
	for i, key := range address {
		keys[i] = GenAccountKey(key)
	}
	values, err := ac.get.Gets(keys)
	if err != nil {
		return nil, err
	}
	var accs []*pbcom.Account
	for _, v := range values {
		if v == nil {
			continue
		}
		acc := &pbcom.Account{}
		err = proto.Unmarshal(v, acc)
		if err != nil {
			continue
		}
		accs = append(accs, acc)
	}
	return accs, nil
}

// KV account to KV
func KV(acc *pbcom.Account) (*pbcom.KeyValue, error) {
	kv := &pbcom.KeyValue{}
	kv.Key = GenAccountKey(acc.InternalAddress)
	v, err := proto.Marshal(acc)
	if err != nil {
		return nil, err
	}
	kv.Value = v
	return kv, nil
}

// GenAccountKey generate account key
func GenAccountKey(address string) []byte {
	return []byte(db.NamespaceAccount + address)
}
